const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 提取js中的css为单独文件 
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css文件 
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// eslint检查js语法 
const EslintWebpackPlugin = require('eslint-webpack-plugin')


// 设置node环境变量
// process.env.NODE_ENV = 'development' 


module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/built.js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            /* 
                1.babel-loader: 
                    js兼容性处理，es5以上的语法转为es5语法 npm i babel-loader @babel/core @babel/preset-env -D 
                    问题：只能转换基本语法，如let -> var，不能处理Promise等高级语法
                2.@babel/polyfill：
                    全部js处理，npm i @babel/polyfill ， 然后在js文件中 import '@babel/polyfill'
                    问题：全部兼容性处理都加进来，体积太大了
                3.core-js
                    npm i core-js -D  需要兼容性处理的就加载，不需要的就不加载。
            */
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    // 预设: 指示babel做怎样的兼容性处理 
                    presets: [
                        [
                            '@babel/preset-env',
                            {
                                // 按需加载 
                                useBuiltIns: 'usage',
                                // 指定corejs版本 
                                corejs: {
                                    version: 3 
                                },
                                // 指定兼容性做到哪个版本的浏览器 
                                targets: {
                                    chrome: '60',
                                    firefox: '60',
                                    ie: '9',
                                    safari: '10',
                                    edge: '17'
                                }
                            }
                        ]
                        
                    ]
                }
            },
            // 处理css资源，样式资源会打包到js中，所以不会输出单独的样式文件 
            {
                test: /\.css$/,
                use: [
                    // 从底向上依次执行 
                    // 'style-loader',  // js代码中创建style标签，将样式放入 
                    MiniCssExtractPlugin.loader, // 取代style-loader，作用：提取js中的css成单独文件 
                    'css-loader', // 将css文件整合到js中 
                    /*
                        css兼容性处理：postcss -> npm i postcss-loader  postcss-preset-env 
                        这个loader能帮助css识别某些环境，从而加载指定的配置，能够兼容到某个浏览器的版本 
                        两种用法：
                            1.使用loader的默认配置 直接写字符串 'postcss-loader'；
                            2.修改loader配置，对象方式；
                    */
                   {
                       loader: 'postcss-loader',
                       options: {
                           postcssOptions: {
                                plugins: [
                                    // postcss的插件 
                                    /* 
                                        postcss-preset-env这个插件帮助postcss找到package.json中browserslist里面的配置，通过配置加载指定
                                        的css兼容性样式。
                                        注：package.json跟node_modules在同级目录。 

                                        "browserslist": {
                                            // 开发环境 --> 设置node环境变量：process.env.NODE_ENV = development 
                                            "development": [
                                            "last 1 chrome version",
                                            "last 1 firefox version",
                                            "last 1 safari version"
                                            ],
                                            // 生产环境：默认看生产环境 
                                            "production": [
                                            ">0.2%",
                                            "not dead",
                                            "not op_mini all"
                                            ]
                                        }

                                    */ 
                                    require('postcss-preset-env')()
                                ]
                           }
                       }
                   }

                ]
            },
            // 处理html中的图片资源，如img标签引入的图片 
            {
                test: /\.html$/,
                loader: 'html-loader',
            },
        ]
    },
    plugins: [
        // html处理 
        new HtmlWebpackPlugin({
            template: './src/index.html',
            // 压缩html 
            minify: {
                collapseWhitespace: true,
                removeComments: true 
            } 
        }),
        // 从js中提取css为单独文件 
        new MiniCssExtractPlugin({
            // 对输出的文件重命名 
            filename: 'css/built.css'
        }),
        // 压缩css文件 
        new optimizeCssAssetsWebpackPlugin(),
        //  
        /* 
                eslint检查js语法 
                注意：只检查自己写的源代码，不检查第三方库。
                设置检查规则：
                    package.json中eslintConfig中设置  
                        "eslintConfit": {
                            "extends": "airbnb-base" 
                        }
                    npm i eslint eslint-webpack-plugin 
                    airbnb --> npm i eslint-loader eslint-config-airbnb-base eslint-plugin-import 

                
            */
        new EslintWebpackPlugin({
            extensions: ['js'],
            context: resolve('src'),
            exclude: '/node_modules',
            fix: true // 自动修复不合理写法 
        }) 
    ],
    // npx webpack-dev-server 
    devServer: {
        static: resolve(__dirname, 'build'),
        compress: true,
        port: 3000,
        open: true, // 自动打开浏览器 
        hot: true // 一个模块更新，只打包这个一模块 
    },
    mode: 'development',
    // 生产环境会自动压缩js代码 
    // mode: 'production' 
}




